package com.zmzncs.lmtc.module.promotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmzncs.lmtc.common.pojo.enums.optionalvalue.promotion.MonthRentTypeEnum;
import com.zmzncs.lmtc.common.util.ExceptionUtil;
import com.zmzncs.lmtc.common.util.JwtUtil;
import com.zmzncs.lmtc.module.customer.dao.CardDao;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.pojo.park_info.ParkInfoDTO;
import com.zmzncs.lmtc.module.promotion.dao.MonthRuleParkMapper;
import com.zmzncs.lmtc.module.promotion.dao.MonthRuleFeeScaleMapper;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule.*;
import com.zmzncs.lmtc.module.promotion.dao.MonthRuleMapper;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule_fee_scale.MonthRuleFeeScaleDTO;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule_park.MonthRulePark;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule_fee_scale.MonthRuleFeeScale;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule_park.MonthRuleParkDTO;
import com.zmzncs.lmtc.module.promotion.service.MonthRuleParkService;
import com.zmzncs.lmtc.module.promotion.service.MonthRuleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmzncs.lmtc.module.system.pojo.user.UserLoginVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-08-12
 */
@Service
@Slf4j
public class MonthRuleServiceImpl extends ServiceImpl<MonthRuleMapper, MonthRule> implements MonthRuleService {

    @Autowired
    MonthRuleMapper monthRuleMapper;
    @Autowired
    MonthRuleParkMapper monthRuleParkMapper;
    @Autowired
    MonthRuleFeeScaleMapper monthRuleFeeScaleMapper;
    @Autowired
    private ParkInfoDao parkInfoDao;
    @Autowired
    MonthRuleParkService monthRuleParkService;
    @Autowired
    CardDao cardDao;

    @Autowired
    HttpServletRequest request;

    /**
     * 添加月租规则
     */
    @Override
    @Transactional
    public void addMonthRule(MonthRuleAddForm form) {
        UserLoginVO loginUser = JwtUtil.getLoginUser(request);

        List<MonthRuleDTO> ruleByNameList = monthRuleMapper.getMonthRuleByName(form.getRuleName());
        if (ruleByNameList.size() > 0) {
            ExceptionUtil.businessException("规则名称【" + form.getRuleName() + "】已存在");
        }

        //  已有规则的停车场
        List<MonthRulePark> monthRuleParkList = monthRuleParkMapper.selectList(null);
        List<Long> hasRuleParkIdList = monthRuleParkList.stream().map(MonthRulePark::getParkId).collect(Collectors.toList());

        //  校验停车场是否已经有其他月租规则
        for (Long parkId : form.getParkIds()) {
            if (hasRuleParkIdList.contains(parkId)) {
                ExceptionUtil.businessException("停车场id为" + parkId + "的停车场已经有其他月租规则");
            }
        }

        //  如果匹配所有停车场，查询所有停车场id集合
        if (form.getIfAllParks().equals(1)) {
            if (monthRuleParkList.size() != 0) {
                ExceptionUtil.businessException("已有停车场存在规则，全部停车场不可选");
            }
            //  查询所有停车场
            List<ParkInfoDTO> parkList = parkInfoDao.getParks();
            List<Long> parkIdList = parkList.stream().map(ParkInfoDTO::getId).collect(Collectors.toList());
            form.setParkIds(parkIdList);
        }

        //  添加月租规则
        MonthRule monthRule = new MonthRule();
        BeanUtils.copyProperties(form, monthRule);
        monthRule.setCreateUserId(loginUser.getUserId());
        monthRuleMapper.insert(monthRule);

        //  添加月租规则的停车场
        List<MonthRulePark> addMonthRuleParkList = new ArrayList<>();
        for (Long parkId : form.getParkIds()) {
            MonthRulePark monthRulePark = new MonthRulePark();
            monthRulePark.setMonthRuleId(monthRule.getId());   //  月租规则id
            monthRulePark.setParkId(parkId); //  停车场id
            addMonthRuleParkList.add(monthRulePark);
        }
        monthRuleParkService.saveBatch(addMonthRuleParkList);

        //  添加月付金额
        if (form.getMonthAmount() != null) {
            MonthRuleFeeScale monthRuleFeeScale = new MonthRuleFeeScale();
            monthRuleFeeScale.setMonthRuleId(monthRule.getId());   //  月租规则id
            monthRuleFeeScale.setAmount(form.getMonthAmount()); //  月付金额
            monthRuleFeeScale.setDays(form.getMonthDays());
            monthRuleFeeScale.setMonthRentType(MonthRentTypeEnum.MONTH.getCode()); //  月付类型（1：月付，2：季付，3：年付）
            monthRuleFeeScale.setMonthRentName("月卡");
            monthRuleFeeScaleMapper.insert(monthRuleFeeScale);
        }

        //  添加季付金额
        if (form.getQuarterAmount() != null) {
            MonthRuleFeeScale quarterAmountmonthRentType = new MonthRuleFeeScale();
            quarterAmountmonthRentType.setMonthRuleId(monthRule.getId());   //  月租规则id
            quarterAmountmonthRentType.setAmount(form.getQuarterAmount()); //  季付金额
            quarterAmountmonthRentType.setDays(form.getQuarterDays());
            quarterAmountmonthRentType.setMonthRentType(MonthRentTypeEnum.QUARTER.getCode()); //  季付类型（1：月付，2：季付，3：年付）
            quarterAmountmonthRentType.setMonthRentName("季卡");
            monthRuleFeeScaleMapper.insert(quarterAmountmonthRentType);
        }

        //  添加年付金额
        if (form.getYearAmount() != null) {
            MonthRuleFeeScale yearAmountPaytype = new MonthRuleFeeScale();
            yearAmountPaytype.setMonthRuleId(monthRule.getId());   //  月租规则id
            yearAmountPaytype.setAmount(form.getYearAmount()); //  年付金额
            yearAmountPaytype.setDays(form.getYearDays());
            yearAmountPaytype.setMonthRentType(MonthRentTypeEnum.YEAR.getCode()); //  年付类型（1：月付，2：季付，3：年付）
            yearAmountPaytype.setMonthRentName("年卡");
            monthRuleFeeScaleMapper.insert(yearAmountPaytype);
        }

    }

    /**
     * 修改月租规则
     */
    @Override
    @Transactional
    public void updateMonthRule(MonthRuleUpdateForm form) {
        UserLoginVO loginUser = JwtUtil.getLoginUser(request);

        List<MonthRuleDTO> ruleByNameList = monthRuleMapper.getMonthRuleByName(form.getRuleName());
        if (ruleByNameList.size() > 0) {
            List<Long> ruleIdList = ruleByNameList.stream().map(MonthRuleDTO::getId).collect(Collectors.toList());
            if (!ruleIdList.contains(form.getId())) {
                ExceptionUtil.businessException("规则名称【" + form.getRuleName() + "】已存在");
            }
        }

        //  已有规则的停车场
        List<MonthRuleParkDTO> monthRuleParkDTOList = monthRuleParkMapper.getDurationRuleExcludeParkList(form.getId());
        //  其他已有规则的停车场id集合
        List<Long> otherParkIdList = monthRuleParkDTOList.stream().map(MonthRuleParkDTO::getParkId).collect(Collectors.toList());

        //  校验停车场是否已经有其他月租规则
        for (Long parkId : form.getParkIds()) {
            if (otherParkIdList.contains(parkId)) {
                ExceptionUtil.businessException("停车场id为" + parkId + "的停车场已经有其他月租规则");
            }
        }

        //  如果匹配所有停车场，查询所有停车场id集合
        if (form.getIfAllParks().equals(1)) {
            Integer monthRuleParkCount = monthRuleParkMapper.selectCount(null);
            if (monthRuleParkCount > 0) {
                ExceptionUtil.businessException("已有停车场存在规则，全部停车场不可选");
            }
            //  查询所有停车场
            List<ParkInfoDTO> parkList = parkInfoDao.getParks();
            List<Long> parkIdList = parkList.stream().map(ParkInfoDTO::getId).collect(Collectors.toList());

            form.setParkIds(parkIdList);
        }

        //  修改月租规则
        MonthRule monthRule = new MonthRule();
        BeanUtils.copyProperties(form, monthRule);
        monthRule.setCreateUserId(loginUser.getUserId());
        monthRuleMapper.updateById(monthRule);

        //*********************修改停车场
        //  删除旧的停车场数据
        LambdaUpdateWrapper<MonthRulePark> monthRuleParkWrapper = new LambdaUpdateWrapper();
        monthRuleParkWrapper.eq(MonthRulePark::getMonthRuleId, form.getId());
        monthRuleParkMapper.delete(monthRuleParkWrapper);
        //  添加新的月租规则的停车场
        List<MonthRulePark> addMonthRuleParkList = new ArrayList<>();
        for (Long parkId : form.getParkIds()) {
            MonthRulePark monthRulePark = new MonthRulePark();
            monthRulePark.setMonthRuleId(monthRule.getId());   //  月租规则id
            monthRulePark.setParkId(parkId); //  停车场id
            addMonthRuleParkList.add(monthRulePark);
        }
        monthRuleParkService.saveBatch(addMonthRuleParkList);

        //  *******************收费标准
        //  删除旧的收费标准
        LambdaUpdateWrapper<MonthRuleFeeScale> monthRulePaytypeWrapper = new LambdaUpdateWrapper();
        monthRulePaytypeWrapper.eq(MonthRuleFeeScale::getMonthRuleId, form.getId());
        monthRuleFeeScaleMapper.delete(monthRulePaytypeWrapper);
        //  ****************添加新的月租规则的收费标准
        //  添加月付金额
        if (form.getMonthAmount() != null) {
            MonthRuleFeeScale monthAmountPaytype = new MonthRuleFeeScale();
            monthAmountPaytype.setMonthRuleId(monthRule.getId());   //  月租规则id
            monthAmountPaytype.setAmount(form.getMonthAmount()); //  月付金额
            monthAmountPaytype.setMonthRentType(MonthRentTypeEnum.MONTH.getCode()); //  月付类型（1：月付，2：季付，3：年付）
            monthAmountPaytype.setMonthRentName("月卡");
            monthRuleFeeScaleMapper.insert(monthAmountPaytype);
        }

        //  添加季付金额
        if (form.getQuarterAmount() != null) {
            MonthRuleFeeScale quarterAmountPaytype = new MonthRuleFeeScale();
            quarterAmountPaytype.setMonthRuleId(monthRule.getId());   //  月租规则id
            quarterAmountPaytype.setAmount(form.getQuarterAmount()); //  季付金额
            quarterAmountPaytype.setMonthRentType(MonthRentTypeEnum.QUARTER.getCode()); //  季付类型（1：月付，2：季付，3：年付）
            quarterAmountPaytype.setMonthRentName("季卡");
            monthRuleFeeScaleMapper.insert(quarterAmountPaytype);
        }

        //  添加年付金额
        if (form.getYearAmount() != null) {
            MonthRuleFeeScale yearAmountPaytype = new MonthRuleFeeScale();
            yearAmountPaytype.setMonthRuleId(monthRule.getId());   //  月租规则id
            yearAmountPaytype.setAmount(form.getYearAmount()); //  年付金额
            yearAmountPaytype.setMonthRentType(MonthRentTypeEnum.YEAR.getCode()); //  年付类型（1：月付，2：季付，3：年付）
            yearAmountPaytype.setMonthRentName("年卡");
            monthRuleFeeScaleMapper.insert(yearAmountPaytype);
        }
    }

    /**
     * 获取月租规则
     */
    @Override
    public IPage<MonthRuleDTO> getMonthRuleParkList(Page page, String keyword) {
        IPage<MonthRuleDTO> monthRuleParkPage = monthRuleMapper.getMonthRuleParkList(page, keyword);
        //  收费标准
        for (MonthRuleDTO ruleDTO : monthRuleParkPage.getRecords()) {
            //  查询规则的收费标准
            List<MonthRuleFeeScaleDTO> monthRuleFeeScaleDTOList = monthRuleFeeScaleMapper.getMonthRuleFeeScaleByRuleId(ruleDTO.getId());
            ruleDTO.setFeeScaleList(monthRuleFeeScaleDTOList);
        }

        return monthRuleParkPage;
    }

    /**
     * 查询咪网月租车规则
     */
    @Override
    public IPage<ParkInfoDTO> getMWMonthRule(MWMonthRuleListForm form) {

        //查询所有咪网停车场
        Page<Object> page = new Page<>(form.getCurrentPage(), form.getPageSize());
        IPage<ParkInfoDTO> iPage = parkInfoDao.getMWParkList(page,form.getParkName());

        List<ParkInfoDTO> mwParks = iPage.getRecords();
        if (mwParks != null && !mwParks.isEmpty()) {
            for (ParkInfoDTO mwPark : mwParks) {

                //查询咪网停车场月租车规则
                List<MWMonthRule> monthRules = monthRuleMapper.getMWMonthRuleByParkId(mwPark.getId(),form.getStatus());
                if (monthRules != null && !monthRules.isEmpty()) {
                    mwPark.setRuleCount(monthRules.size());//月租车规则数量
                    mwPark.setMonthRuleList(monthRules);//月租车规则信息
                    //查询使用停车场月租服务的用户数量
                    Long custCount = cardDao.getMWMonthCustCount(mwPark.getId());
                    mwPark.setCarCount(custCount.intValue());//拥有月租车数量
                } else {
                    mwPark.setRuleCount(0);
                    mwPark.setCarCount(0);
                }
            }
        }
        return iPage;
    }

    @Override
    public IPage<MonthRuleDTO> getMonthName(MonthRuleNameForm form) {
        Page<Object> page = new Page<>(form.getPage(), form.getSize());
        IPage<MonthRuleDTO> iPage = monthRuleMapper.getMonthName(page,form.getRuleName());
        return iPage;
    }

}
